﻿using System;
using System.Collections.Generic;
using System.Data;
using System.ServiceModel;
using System.ServiceModel.Channels;
using RemoteTestRunner.BusinessLogic;
using RemoteTestRunner.WCFService;

namespace RemoteTestRunner.ServiceFacade
{
    public class ServerFacade : IRTRService
    {
        #region Private Attributes

        private RTRService.RTRServiceClient _proxy;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ServerFacade"/> class.
        /// </summary>
        /// <param name="serviceUrl">The service URL.</param>
        public ServerFacade(string serviceUrl, int timeoutSeconds)
        {
            _proxy = new RemoteTestRunner.ServiceFacade.RTRService.RTRServiceClient();

            _proxy.Endpoint.Address = new EndpointAddress(
                new Uri(serviceUrl),
                null,
                new AddressHeaderCollection());

            _proxy.Endpoint.Binding.SendTimeout = new TimeSpan(0, 0, timeoutSeconds);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ServerFacade"/> class.
        /// </summary>
        public ServerFacade()
        {
            _proxy = new RemoteTestRunner.ServiceFacade.RTRService.RTRServiceClient();
        }

        #endregion

        #region Interface Methods

        /// <summary>
        /// Gets a list of test projects.
        /// </summary>
        /// <returns>
        /// A <see cref="DataTable"/> containing a list of all test projects.
        /// </returns>
        public DataTable GetTestProjects()
        {
            return _proxy.GetTestProjects();
        }

        /// <summary>
        /// Adds a new test.
        /// </summary>
        /// <param name="projectId">The Project ID the new test is associated with.</param>
        /// <param name="name">The name of the new test.</param>
        /// <returns>
        /// A reference to the new test <see cref="DataRow"/>.
        /// </returns>
        public int AddTest(int projectId, string name)
        {
            return _proxy.AddTest(projectId, name);
        }

        /// <summary>
        /// Deletes the specified test.
        /// </summary>
        /// <param name="testId">The ID of the test to be deleted.</param>
        public void DeleteTest(int testId)
        {
            _proxy.DeleteTest(testId);
        }

        /// <summary>
        /// Gets a list of tests.
        /// </summary>
        /// <returns>
        /// A <see cref="DataTable"/> containing a list of all tests.
        /// </returns>
        public DataTable GetTests()
        {
            return _proxy.GetTests();
        }

        /// <summary>
        /// Gets the specified test row.
        /// </summary>
        /// <param name="testId">The ID of the test to return.</param>
        /// <returns>
        /// A <see cref="DataRow"/> containing the specified test information.
        /// </returns>
        public TestInfo GetTestRow(int testId)
        {
            return _proxy.GetTestRow(testId);
        }

        /// <summary>
        /// Gets a collection of data source information.
        /// </summary>
        /// <param name="appConfigPath">The application configuration file to be parsed.</param>
        /// <returns>
        /// A list of <see cref="DataSourceInfo"/> containing information for each
        /// data source found in the configuration file.
        /// </returns>
        public List<DataSourceInfo> GetDataSources(string appConfigPath)
        {
            return _proxy.GetDataSources(appConfigPath);
        }

        /// <summary>
        /// Gets the test configuration <see cref="DataSet"/>.
        /// </summary>
        /// <returns>
        /// A <see cref="DataSet"/>containing the test configuration.
        /// </returns>
        public DataSet GetTestData()
        {
            return _proxy.GetTestData();
        }

        /// <summary>
        /// Saves the test configuration <see cref="DataSet"/>.
        /// </summary>
        /// <param name="dataSet">The data set.</param>
        public void SaveTestData(DataSet dataSet)
        {
            _proxy.SaveTestData(dataSet);
        }

        /// <summary>
        /// Gets a list of the classes and methods from the unit test assembly.
        /// </summary>
        /// <param name="testId">The ID of the test to process.</param>
        /// <returns>A 2 level hierchial class/method list.</returns>
        public List<TestClass> GetTestMethods(int testId)
        {
            return _proxy.GetTestMethods(testId);
        }

        /// <summary>
        /// Runs the test for the test ID passed in.
        /// </summary>
        /// <param name="testId">The ID of the test to be ran.</param>
        /// <param name="testsToRun">A list of the test to run.  The expected format is 'Class.Method'.</param>
        /// <param name="timeoutSeconds"></param>
        /// <returns>
        /// The path of the generated test results file.
        /// </returns>
        public TestResultSummary RunTest(int testId, List<string> testsToRun, int timeoutSeconds)
        {
            return _proxy.RunTest(testId, testsToRun, timeoutSeconds);
        }

        /// <summary>
        /// Gets the test result history.
        /// </summary>
        /// <param name="testId">The ID of the test.</param>
        /// <returns>A list of test results.</returns>
        public List<TestResultSummary> GetTestResultHistory(int testId)
        {
            return _proxy.GetTestResultHistory(testId);
        }

        /// <summary>
        /// Deletes the test result history items.
        /// </summary>
        /// <param name="historyItemsToDelete">The history items to delete.</param>
        public void DeleteTestResultHistoryItems(List<TestResultSummary> historyItemsToDelete)
        {
            _proxy.DeleteTestResultHistoryItems(historyItemsToDelete);
        }

        /// <summary>
        /// Gets the test result.
        /// </summary>
        /// <param name="path">The path.</param>
        /// <returns>The results of a test.</returns>
        public TestResult GetTestResult(string path)
        {
            return _proxy.GetTestResult(path);
        }

        #endregion
    }
}
